﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Halfpipe.Data.Repository
{
    public interface IRepository<TEntity> where TEntity : class
    {
        /// <summary>
        /// Deletes an entity from the context/database.
        /// </summary>
        /// <param name="entity">An entity used to supply key information. Only the primary key values are important here. Does not have to be attached to a context.</param>
        void Delete(TEntity entity);
        /// <summary>
        /// Deletes all entities from this repository.
        /// </summary>
        void DeleteAll();
        /// <summary>
        /// Insert a new entity into the context/database.
        /// </summary>
        /// <param name="entity">Values for the new entity.</param>
        /// <returns>The newly inserted entity. PK values from the DB won't be populated until you call UnitOfWork.Commit();</returns>
        TEntity Insert(TEntity entity);
        // Select() is reserved by the compiler for LINQ. So we need a different name.
        /// <summary>
        /// Returns a typed query which you can enumerate to get all instances of this type, refine with .Where, project onto a new type, etc. 
        /// To return a single object, you can do something like: repository.SelectAll().Where(o => o.Id == 123).Single();
        /// For a list of POCOs, try var list = repository.SelectAll().Select(o => new PocoObject { Id = o.Id, Data = o.Data });
        /// </summary>
        /// <returns>Strongly-typed query.</returns>
        IQueryable<TEntity> SelectAll();
        /// <summary>
        /// Update an entity in the context/database.
        /// </summary>
        /// <param name="entity">Entity instance used for both key information and new property values.
        /// If the entity is attached (i.e., was returned from Select(), then only modified properties will be saved.
        /// If it's detached, all properties will be assumed to be modified.</param>
        /// <returns>The updated, attached entity.</returns>
        TEntity Update(TEntity entity);
    }
}
